代码坏味道及其重构 3 过长函数
在代码坏味道中,另外一个特征是过长函数。对于动态语言,比如 Python、Ruby,超过 5 行算过长函数。对于静态语言,比如 Java,超过 10、20 行算过长函数。
此问题出现的原因有很多,比如早期开发者因为性能原因,会去减少函数数量和函数调用次数。但是现在编程语言会去优化这方面的性能消耗。同时,代码的可维护性优先级是更高的,所以我们没有必要为了性能原因减少函数数量;还有一些其他原因,把多个业务处理流程放在一个函数实现,把不同层面的细节放到一个函数实现,或者说每次加一点代码,导致最后函数过长。
过长函数会导致很难去命名函数内的变量,容易冲突。
重构方法
对于过长函数这种代码坏味道,99% 情况可以使用提炼函数解决。一般有注释的地方都可以提炼出函数。
提炼函数
function printOwing(invoice) {
printBanner();
let outstanding = calculateOutstanding();
//print details
console.log(`name: ${invoice.customer}`);
console.log(`amount: ${outstanding}`);
}
function printOwing(invoice) {
printBanner();
let outstanding = calculateOutstanding();
printDetails(outstanding);
function printDetails(outstanding) {
console.log(`name: ${invoice.customer}`);
console.log(`amount: ${outstanding}`);
}
}
如果一个函数的代码需要你去阅读一下才能知道它到底在干什么,那就提取函数。保持尽量小的函数。同时,小函数要起一个好的名字。
函数短在现在不会引起调用栈的性能问题。甚至由于语言的优化,越短的函数越容易缓存。
一般来说,可以在此之前使用移动语句。
移动语句
const pricingPlan = retrievePricingPlan();
const order = retreiveOrder();
let charge;
const chargePerUnit = pricingPlan.unit;
const pricingPlan = retrievePricingPlan();
const chargePerUnit = pricingPlan.unit;
const order = retreiveOrder();
let charge;
让存在关联的代码一起出现,更加容易理解。如果几行代码访问了同一个数据,那就放在一起。
对函数内代码,使用移动语句后,可以更容易提炼出函数。